package com.njust.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.extra.template.TemplateException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.njust.Util.ExcelUtil;
import com.njust.constant.Constant;
import com.njust.domain.dto.*;
import com.njust.domain.po.*;
import com.njust.domain.vo.PageQueryVO;
import com.njust.domain.vo.PageQueryVO;
import com.njust.exception.DeleteAccountFailedException;
import com.njust.exception.ProductIsNotExist;
import com.njust.exception.SampleRequestIsNotExist;
import com.njust.exception.TemplateHasException;
import com.njust.mapper.ProductMapper;
import com.njust.mapper.SampleMapper;
import com.njust.mapper.SampleRequestMapper;
import com.njust.service.SampleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @version 1.0
 * @Author Imak
 * @Date 2024/11/14 13:07
 * @样品
 */
@Service
@Slf4j
public class SampleServiceImpl implements SampleService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private SampleMapper sampleMapper;

    @Autowired
    private SampleRequestMapper sampleRequestMapper;

    private final Object lock=new Object();
    /**
     * 添加样品
     * @param sampleCreateDTO
     */
    public void add(SampleCreateDTO sampleCreateDTO) {
        synchronized (lock){
            //判断product_name是否存在
            String product_name= sampleCreateDTO.getProduct_name();
            QueryWrapper<Product> productWrapper = new QueryWrapper<>();
            productWrapper.eq("product_name", product_name);
            Product product = productMapper.selectOne(productWrapper);

            if (product == null) {
                // 产品不存在，不能添加样品
                throw new ProductIsNotExist("产品不存在，请更换产品名称后再添加样品。");
            }
            //存在则插入sample表
            Sample sample=new Sample();
            BeanUtils.copyProperties(sampleCreateDTO,sample);
            sample.setProduct_id(product.getProduct_id());

            sampleMapper.insert(sample);
        }


    }

    /**
     * 批量添加样品
     * @param data
     */
    public void addList(List<SampleCreateDTO> data) {
        synchronized (lock){
            List<Sample> sampleList = new ArrayList<>();

            for (SampleCreateDTO sampleCreateDTO : data) {
                // 判断product_name是否存在
                String product_name = sampleCreateDTO.getProduct_name();
                QueryWrapper<Product> productWrapper = new QueryWrapper<>();
                productWrapper.eq("product_name", product_name);
                Product product = productMapper.selectOne(productWrapper);

                if (product == null) {
                    // 产品不存在，记录错误信息或进行其他处理，这里简单打印错误信息
                    log.info("产品名为{}的产品不存在，该项导入失败！",product_name);
                    continue;
                }

                // 产品存在则创建Sample对象并设置相关属性
                Sample sample = new Sample();
                BeanUtils.copyProperties(sampleCreateDTO, sample);
                sample.setProduct_id(product.getProduct_id());

                sampleList.add(sample);
            }

            if (!sampleList.isEmpty()) {
                // 批量插入sample表
                sampleMapper.insertBatch(sampleList);
            }
        }


    }

    /**
     * 根据id查询样品
     * @param sample_id
     * @return
     */
    public Sample selectById(int sample_id) {
        return sampleMapper.selectById(sample_id);
    }

    /**
     * 修改样品信息
     * @param sampleUpdateDTO
     */
    public void update(SampleUpdateDTO sampleUpdateDTO) {
        synchronized (lock){
            //判断product_name是否存在
            String product_name= sampleUpdateDTO.getProduct_name();
            QueryWrapper<Product> productWrapper = new QueryWrapper<>();
            productWrapper.eq("product_name", product_name);
            Product product = productMapper.selectOne(productWrapper);

            if (product == null) {
                // 产品不存在，不能修改样品信息
                throw new ProductIsNotExist("产品不存在，请更换产品名称后再添加样品。");
            }
            //存在则插入sample表
            Sample sample=new Sample();
            BeanUtils.copyProperties(sampleUpdateDTO,sample);
            sample.setProduct_id(product.getProduct_id());

            sampleMapper.updateById(sample);
        }


    }

    /**
     * 分页查询样品
     * @param samplePageQueryDTO
     * @return
     */
    public PageQueryVO pageQuerySample(SamplePageQueryDTO samplePageQueryDTO) {
        PageHelper.startPage(samplePageQueryDTO.getPage(), samplePageQueryDTO.getPageSize());

        Page<Sample> page=sampleMapper.pageQuerySample(samplePageQueryDTO);
        long total=page.getTotal();
        List<Sample> records=page.getResult();

        return new PageQueryVO(total,records);
    }

    /**
     * 分页查询样品需求表
     * @param sampleRequestPageQueryDTO
     * @return
     */
    public PageQueryVO pageQuerySampleRequest(SampleRequestPageQueryDTO sampleRequestPageQueryDTO) {
        PageHelper.startPage(sampleRequestPageQueryDTO.getPage(), sampleRequestPageQueryDTO.getPageSize());

        Page<SampleRequestPage> page=sampleRequestMapper.pageQuerySampleRequest(sampleRequestPageQueryDTO);
        long total=page.getTotal();
        List<SampleRequestPage> records=page.getResult();

        return new PageQueryVO(total,records);
    }

    /**
     * 修改样品需求状态
     * @param sampleUpdateStatusDTO
     */
    public void updateStatus(SampleUpdateStatusDTO sampleUpdateStatusDTO) {
        synchronized (lock){
            SampleRequest sampleRequest = sampleRequestMapper.selectById(sampleUpdateStatusDTO.getRequest_id());

            if (sampleRequest == null) {
                // 如果未找到对应的记录，返回错误结果
                throw new SampleRequestIsNotExist("对应样品需求记录不存在!");
            }
            if(sampleRequest.getRequest_status()== Constant.ISSUED){
                log.info("样品已发放，禁止修改状态");
            }else{
                sampleRequest.setRequest_status(sampleUpdateStatusDTO.getRequest_status());//更新样品申请状态
            }

            // 更新实际数量
            sampleRequest.setActual_amount(sampleUpdateStatusDTO.getActual_amount());


            // 如果申请状态变为已发放（1），更新样品发放时间为当前时间
            if (sampleUpdateStatusDTO.getRequest_status() == Constant.ISSUED) {
                sampleRequest.setIssue_date(new Date());
            }

            // 执行更新操作
            sampleRequestMapper.updateById(sampleRequest);
        }


    }

    /**
     * 批量添加样品需求 同时记录时间
     * @param sampleRequestCreateDTOList
     */
    public void addRequestList(List<SampleRequestCreateDTO> sampleRequestCreateDTOList) {
        List<SampleRequest> sampleRequests=new ArrayList<>();
        for(SampleRequestCreateDTO sampleRequestCreateDTO:sampleRequestCreateDTOList){
            SampleRequest sampleRequest=new SampleRequest();
            BeanUtils.copyProperties(sampleRequestCreateDTO,sampleRequest);
            //设置状态为申请中
            sampleRequest.setRequest_status(Constant.REQUESTING);
            //设置时间为系统时间
            sampleRequest.setRequest_date(new Date());
            sampleRequests.add(sampleRequest);
        }
        sampleRequestMapper.insertBatch(sampleRequests);
    }

    /**
     * 删除样品需求
     * @param request_id
     * @return
     */
    public void deleteRequest(Integer request_id) {
        sampleRequestMapper.deleteById(request_id);
    }

    /**
     * 修改样品需求
     * @param sampleRequestUpdateDTO
     */
    public void updateRequest(SampleRequestUpdateDTO sampleRequestUpdateDTO) {

        //判断是否存在
        SampleRequest sampleRequest=sampleRequestMapper.selectById(sampleRequestUpdateDTO.getRequest_id());
        if(sampleRequest==null) {
            throw new SampleRequestIsNotExist("该样品需求信息不存在");
        }
        // 设置要更新的字段值
        sampleRequest.setRequested_text(sampleRequestUpdateDTO.getRequested_text());
        // 更新申请需求时间为当前时间
        sampleRequest.setRequest_date(new Date());

        // 执行更新操作
        sampleRequestMapper.updateById(sampleRequest);


    }

    /**
     * 导出样品需求excel表
     * @param response
     */
    public void exportExcel(HttpServletResponse response) {

        //准备导出数据
        List<SampleRequestPage> sampleRequestList = sampleRequestMapper.selectAllPage();

        try {
            // 读取Excel模板文件
            FileInputStream inputStream = new FileInputStream("src/main/resources/templates/清单.xlsx");
            Workbook workbook = new XSSFWorkbook(inputStream);
            inputStream.close();
            // 标记是否找到指定名称的Sheet
            boolean sheetFound = false;

            // 获取模板中的Sheet页数量
            int sheetCount = workbook.getNumberOfSheets();

            // 遍历所有Sheet，找到指定名称的Sheet并删除其他Sheet
            for (int i = 0; i < sheetCount; i++) {
                Sheet sheet = workbook.getSheetAt(i);
                if (sheet.getSheetName().equals("样品需求清单")) {
                    sheetFound = true;
                } else {
                    workbook.removeSheetAt(i);
                    i--;
                    sheetCount--;
                }
            }

            // 如果没有找到指定名称的Sheet，抛出异常
            if (!sheetFound) {
                throw new IllegalArgumentException("未在模板文件中找到名为'样品需求清单'的Sheet。");
            }


            // 获取模板中的Sheet页
            Sheet sheet = workbook.getSheet("样品需求清单");

            // 清空模板中的示例数据（从第二行开始，第一行是表头）
            int lastRowNum = sheet.getLastRowNum();
            for (int i = lastRowNum; i >= 1; i--) {
                Row row = sheet.getRow(i);
                if (row!= null) {
                    sheet.removeRow(row);
                }
            }

            // 定义日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

            // 遍历查询到的数据库数据列表，将数据填充到Excel表格中
            int rowIndex = 1;
            for (SampleRequestPage sampleRequest : sampleRequestList) {
                Row dataRow = sheet.createRow(rowIndex++);

                // 根据实体类属性将数据填充到对应的单元格
                dataRow.createCell(0).setCellValue(sampleRequest.getUName());
                dataRow.createCell(1).setCellValue(sampleRequest.getProduct_name());
                dataRow.createCell(2).setCellValue(sampleRequest.getStandard_number());
                dataRow.createCell(3).setCellValue(sampleRequest.getProduct_name());
                dataRow.createCell(4).setCellValue(sampleRequest.getMode_specification());
                dataRow.createCell(5).setCellValue(sampleRequest.getRequested_text());
                dataRow.createCell(6).setCellValue(sampleRequest.getSample_name());
                dataRow.createCell(7).setCellValue(sampleRequest.getManufacturer());
                dataRow.createCell(8).setCellValue(sampleRequest.getActual_amount());

                // 设置日期格式并填充日期数据
                Date requestDate = sampleRequest.getRequest_date();
                if (requestDate!= null) {
                    dataRow.createCell(9).setCellValue(dateFormat.format(requestDate));
                } else {
                    dataRow.createCell(9).setCellValue("");
                }

                Date issueDate = sampleRequest.getIssue_date();
                if (issueDate!= null) {
                    dataRow.createCell(10).setCellValue(dateFormat.format(issueDate));
                } else {
                    dataRow.createCell(10).setCellValue("");
                }
            }

            // 将填充好数据的Excel文件保存到本地
            //FileOutputStream outputStream = new FileOutputStream("样品需求清单.xlsx");
            ServletOutputStream outputStream=response.getOutputStream();
            String encodedFileName = URLEncoder.encode("样品需求清单.xlsx", "UTF-8");
            response.setHeader("Content-disposition","attachment;filename=\""+encodedFileName+"\"");
            workbook.write(outputStream);
            outputStream.close();
            workbook.close();
            log.info("数据已成功导出到Excel文件！");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 删除样品
     * @param sample_id
     */
    public void delete(Integer sample_id) {
        //先删样品需求表
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("sample_id",sample_id);
        sampleRequestMapper.delete(wrapper);
        sampleMapper.deleteById(sample_id);

    }


}
